package Simulation;

import IA.ClockObserverInterface;
import IA.InformationAggregator;
import IA.Service;
import IA.ServiceObserverInterface;
import commands.CmdCallNextWaitParty;
import commands.CmdClearTable;
import commands.CmdEndService;
import commands.CmdHandleCustomerArrival;

/**
 * @author Rob Leister rleist1@students.towson.edu
 *
 */
public class CustomerSimulator implements ClockObserverInterface, ServiceObserverInterface {

    private int ArrivalDelay;
    private int customerArrivalCountdown;
    int[] PartySizes = {1, 2, 3, 4}; //array of possible party sizes
    int[] PartyWeights = {10, 20, 30, 40}; //% chance that each corresponding party size will arrive
    int EatTime = 20; //# of ticks (1 tick = 1 minute)
    int DeltaEatTime = 5; // +/- for random generation
    private InformationAggregator ia;

    public CustomerSimulator(InformationAggregator ia) {
        ArrivalDelay = 20; // initial setting
        customerArrivalCountdown = 0;
        this.ia = ia;
    }

    @Override
    public void clockTick() {
        customerArrivalCountdown--;
        if (customerArrivalCountdown <= 0) {
            customerArrivalCountdown = ArrivalDelay;
            int NumPeople = new WeightedRandParam(PartySizes, PartyWeights).generateValue();
            Service s = (Service)new CmdHandleCustomerArrival(ia, NumPeople, new RandParam(EatTime - DeltaEatTime, EatTime + DeltaEatTime).IntValue()).execute();
            if(s != null) s.AddObserver(this);
        }
    }

    public int getArrivalDelay() {
        return ArrivalDelay;
    }

    public void setArrivalDelay(int customerFlowIn) {
        this.ArrivalDelay = customerFlowIn;
    }

    @Override
    public void notifyServiceComplete(Service s) {
        //tell service collection that its finished
        //free up table
        new CmdEndService(ia, s).execute();
        new CmdClearTable(ia, s.getTableID()).execute();
        //process next customer from queue
        //if no customers, or none can fit, command will do nothing (no need to check here)
        Service ns = (Service)new CmdCallNextWaitParty(ia).execute();
        if(ns != null) ns.AddObserver(this);
    }


    public int getEatTime() {
        return EatTime;
    }

    public void setEatTime(int EatTime) {
        this.EatTime = EatTime;
    }


} // end class CustomerSimulator
